/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "Vk缓存.h"

#include "S_键值序列容器.h"
#include "core/引擎配置.h"
#include "底层绘图/底层绘图框架.h"
//static S_键值序列容器<uint32, S_VkUniform缓存*> m_场景容器;
#include <mutex>

static std::map<S_板载缓存*, std::vector<std::unique_ptr<C_缓存列队数据>>> g缓存拷贝列队;



VkBufferUsageFlags f_getAPI缓存类型(E_板载缓存类型 memType) {
	uint32 mt = 0;

	switch (memType) {
	case e_VBO:		mt = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; break;
	case e_UBO:		mt = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; break;
	case e_TBOs:	mt = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; break;
	case e_INDEX:	mt = VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; break;
	case e_SSBO:	mt = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; break;
	case e_SSBOd:	mt = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; break;
	case e_INDIRECT:	mt	=	VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT; break;

	case e_光追实例:	mt	=	VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
						break;
	
	case e_光追顶层加速结构: mt = VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR; break;
	case e_光追底层加速结构: mt =	VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR |
									VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT; break;
	case e_着色列表:		mt =	VK_BUFFER_USAGE_TRANSFER_SRC_BIT | 
									VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT|
									VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR ; 
		break;

	default:
		break;
	}

	mt |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;

	return mt;
}

uint32 f_getAPI光追加速缓存类型(E_板载缓存类型 memType) {
	uint32 mt = 0;
	
	switch (memType) {
		case e_光追实例:	mt = 
			VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR |
			VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT                                  |
			VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
			break;

		case e_光追顶层加速结构: mt = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR; break;
		case e_光追底层加速结构: mt = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR; break;

		default:
			break;
	}
	return mt;
}






Inline uint8* f_bm_ptr(S_GPU内存块& m, uint64 offset = 0) {
	return  &(((uint8*)(m.m_Buf->m_mappedPtr))[(m.m_Mem.m_偏移 + offset) * m.m_Buf->m_Offset]);
}

void f_bm_insert(S_GPU内存块& m, uint32 插入位置, const uint8* data, uint32 num) {
	if(!num) return;

	S_GPU内存块 新块 = f_bm_alloc(m.m_Buf, m.m_Mem.m_数量 + num);

	auto* 读内存 = f_bm_ptr(m);
	auto* 写内存 = f_bm_ptr(新块);

	//前一节复制
	memcpy(写内存, 读内存, 插入位置 * 新块.m_Buf->m_Offset);

	//新数据复制
	写内存 = f_bm_ptr(新块, 插入位置);
	memcpy(写内存, data, num * 新块.m_Buf->m_Offset);

	//后一节复制
	读内存 = f_bm_ptr(m, 插入位置);
	写内存 = f_bm_ptr(新块, 插入位置 + num);
	memcpy(写内存, 读内存, (m.m_Mem.m_数量 - 插入位置) * 新块.m_Buf->m_Offset);

	f_bm_erase(m);
	m = 新块;
}

void f_bm_insert(S_GPU内存块& m, const S_GPU内存块& data, uint32 offset) {
	//const S_VkBuffer& tData = *((S_VkBuffer*)sObj);
	//S_绘图设备配置* 绘图配置 = (S_绘图设备配置*)f_df_get绘图环境(m.m_Buf->m_Ctx);
	//
	//f_bm_resize(m, m.m_Mem.m_数量 + data.m_Mem.m_数量);
	//
	//VkBufferCopy copyRegion = {};
	//copyRegion.srcOffset = 0; // 从源缓冲区的偏移量
	//copyRegion.dstOffset = 0; // 目标缓冲区的偏移量
	//copyRegion.size = size; // 要复制的字节大小
	//
	//auto cmd = f_vk创建命令缓存(绘图配置);
	//f_vk绑定命令缓存(绘图配置, cmd);
	//vkCmdCopyBuffer(cmd, ((S_VkBuffer*)m.m_Buf)->m_Buf, ((S_VkBuffer*)data.m_Buf)->m_Buf, 1, &copyRegion);
	//f_vk刷新命令缓存(绘图配置, cmd, true);
}

void f_bm_remove(S_GPU内存块& m, uint32 删除位置) {
	auto* 内存 = f_bm_ptr(m);

	for (uint32 i = 删除位置 + 1; i < m.m_Mem.m_数量; ++i) {
		memcpy(&内存[i-1], &内存[i], m.m_Buf->m_Offset);
	}

	f_bm_resize(m, m.m_Mem.m_数量 - 1);
}

void f_bm_刷新GPU内存(S_板载缓存* buf) {
	return;
	S_VkArray缓存* gpuBuf = (S_VkArray缓存*)buf;
	VkMappedMemoryRange range{};
	range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
	range.memory = gpuBuf->m_Data.m_Mem;
	range.offset = 0;
	range.size = gpuBuf->m_Data.m_Buffer_info.range;
	vkFlushMappedMemoryRanges(gpuBuf->m_Data.m_设备, 1, &range);
}




S_VkArray缓存::S_VkArray缓存(S_设备环境& ctx, uint16 offset, E_板载缓存类型 type, uint64 size) {
	m_Data = { 0,0,0, {0} };
	m_Ctx = ctx;

	m_Size = size;
	m_Offset = offset;
	m_Type = type;
	m_VkBufferUsageFlags = f_getAPI缓存类型(type);
	m_光追加速结构 = nullptr;

	if (m_Size) {
		f_分配(m_VkBufferUsageFlags, offset * m_Size);
	}
}

S_VkArray缓存::S_VkArray缓存(S_设备环境& ctx, E_板载缓存类型 type, VkBufferUsageFlags typeflags, uint16 offset, uint64 size) {
	m_Data = { 0,0,0, {0} };
	m_Ctx = ctx;

	m_Size = size;
	m_Offset = offset;
	m_Type = type;
	m_VkBufferUsageFlags = typeflags;
	m_光追加速结构 = nullptr;

	if (type == E_板载缓存类型::e_UBO && !m_Size) {
		m_Size = 1;
	}
	if (m_Size) {
		f_分配(typeflags, offset * m_Size);
	}
}

S_VkArray缓存::S_VkArray缓存(S_设备环境& ctx, E_板载缓存类型 type, uint16 offset, uint64 size) {
	m_Ctx = ctx;
	m_Size = size;
	m_Offset = offset;
	m_Type = type;
	m_VkBufferUsageFlags = VkBufferUsageFlagBits::VK_BUFFER_USAGE_TRANSFER_SRC_BIT;

	elt_capacity = m_Size * offset + 4;
	m_预分配空间 = false;

	f_分配拷贝缓存();
}

S_VkArray缓存::~S_VkArray缓存() {
	if (m_光追加速结构) {
		auto di = f_vk_get绘图环境(m_Ctx);
		//di->vkDestroyAccelerationStructure(m_Data.m_设备, m_光追加速结构, nullptr);
		m_光追加速结构 = nullptr;
	}

	if (m_Data.m_Buf) vkDestroyBuffer(m_Data.m_设备, m_Data.m_Buf, 0);
	if (m_Data.m_Mem) vkFreeMemory(m_Data.m_设备, m_Data.m_Mem, 0);
}

uint32 S_VkArray缓存::f_分配(VkBufferUsageFlags type, uint64 BitSize) {
	std::lock_guard 锁(m_分配内存锁);
	
	m_GPU_Address = 0;
	
	auto di = f_vk_get绘图框架(m_Ctx);
	auto& pp = f_vk_get物理设备属性(m_Ctx);
	m_Data.m_设备 = (VkDevice)(m_Ctx.m_逻辑设备.设备);
	
	

	if (m_Data.m_Buf) {
		vkFreeMemory(m_Data.m_设备, m_Data.m_Mem, 0);
		vkDestroyBuffer(m_Data.m_设备, m_Data.m_Buf, 0);
	}


	VkBufferCreateInfo buf_info = {};
	buf_info.sType					= VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
	buf_info.pNext					= NULL;
	buf_info.usage					= type;
	buf_info.size					= BitSize;
	buf_info.queueFamilyIndexCount	= 0;
	buf_info.pQueueFamilyIndices	= NULL;
	buf_info.sharingMode			= VK_SHARING_MODE_EXCLUSIVE;
	buf_info.flags					= 0;


	if (pp.m_支持光追) {
		switch (m_Type) {
			case E_板载缓存类型::e_光追底层加速结构:
			case E_板载缓存类型::e_光追顶层加速结构: {
				buf_info.usage |= VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR;
				break;
			}
			default:
				break;
		}
	}
	

	VkResult res = vkCreateBuffer(m_Data.m_设备, &buf_info, NULL, &m_Data.m_Buf);
	assert(res == VK_SUCCESS);


	VkMemoryRequirements 内存请求信息;
	vkGetBufferMemoryRequirements(m_Data.m_设备, m_Data.m_Buf, &内存请求信息);
	assert(BitSize <= 内存请求信息.size);

	VkMemoryAllocateInfo 内存分配信息;
	VkMemoryAllocateFlagsInfoKHR allocFlagsInfo{};
	{
		内存分配信息.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
		内存分配信息.pNext = NULL;
		内存分配信息.allocationSize = 内存请求信息.size;
		
		VkFlags 内存类型配置 = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
		if (m_流 == false) {
			内存类型配置 |= VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
		}

		switch (m_Type) {
			case E_板载缓存类型::e_图像缓存:
			case E_板载缓存类型::e_光追底层加速结构:
			case E_板载缓存类型::e_光追顶层加速结构: {
				内存分配信息.memoryTypeIndex = f_内存类型索引(pp.m_内存属性, 内存请求信息.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
				break;
			}
			
			case E_板载缓存类型::e_UBO: {
				内存分配信息.memoryTypeIndex = f_内存类型索引(pp.m_内存属性, 内存请求信息.memoryTypeBits, 内存类型配置 );
				break;
			}
			default: {
				内存分配信息.memoryTypeIndex = f_内存类型索引(pp.m_内存属性, 内存请求信息.memoryTypeBits, 内存类型配置 );
				
				
				if (buf_info.usage & VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT) {
					
					allocFlagsInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO_KHR;
					allocFlagsInfo.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT;

					内存分配信息.pNext = &allocFlagsInfo;
				}
				break;
			}
		}

		
	}

	
	
	res = vkAllocateMemory(m_Data.m_设备, &内存分配信息, NULL, &(m_Data.m_Mem));
	if (res != VK_SUCCESS) {
		
		if (m_Data.m_Buf) {
			vkFreeMemory(m_Data.m_设备, m_Data.m_Mem, 0);
			vkDestroyBuffer(m_Data.m_设备, m_Data.m_Buf, 0);

			m_Data.m_Mem = nullptr;
			m_Data.m_Buf = nullptr;
		}

		DEF_记录日志("error 分配GPU内存失败 vkAllocateMemory");
		//m_分配内存锁.unlock();
		std::cout<<"error 分配GPU内存失败:"<< res << std::endl;
		return -1;
	}
	
	
	m_Data.m_Buffer_info.buffer = m_Data.m_Buf;
	m_Data.m_Buffer_info.offset = 0;
	m_Data.m_Buffer_info.range = BitSize;
	vkBindBufferMemory(m_Data.m_设备, m_Data.m_Buf, m_Data.m_Mem, 0);

	elt_capacity = BitSize;

	switch (m_Type) {
		case E_板载缓存类型::e_光追底层加速结构: 
		case E_板载缓存类型::e_光追顶层加速结构: {
			VkAccelerationStructureCreateInfoKHR 加速结构创建信息{};
			加速结构创建信息.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR;
			加速结构创建信息.buffer = m_Data.m_Buf;
			加速结构创建信息.type = VkAccelerationStructureTypeKHR(f_getAPI光追加速缓存类型(m_Type));
			加速结构创建信息.size = m_Size * m_Offset;
			加速结构创建信息.offset = 0;
		
			di->vkCreateAccelerationStructure(m_Data.m_设备, &加速结构创建信息, nullptr, &m_光追加速结构);
			break;
		}
		default:
			break;
	}
	return 0;
}

uint32 S_VkArray缓存::f_分配拷贝缓存() {
	m_Data.m_设备 = f_vk_getDevice(m_Ctx);
	auto& pp = f_vk_get物理设备属性(m_Ctx);
	VkResult err{};

	VkBufferCreateInfo bufferInfo{};
	bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
	bufferInfo.size = elt_capacity;
	bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
	bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;

	err = vkCreateBuffer(m_Data.m_设备, &bufferInfo, nullptr, &m_Data.m_Buf);
	if (err != VK_SUCCESS) {
		throw std::runtime_error("创建CPU专属Buffer失败");
	}

	VkMemoryRequirements 内存请求信息;
	vkGetBufferMemoryRequirements(m_Data.m_设备, m_Data.m_Buf, &内存请求信息);

	VkMemoryAllocateInfo 内存分配信息;
	VkMemoryAllocateFlagsInfoKHR allocFlagsInfo{};
	内存分配信息.memoryTypeIndex = f_内存类型索引(pp.m_内存属性, 内存请求信息.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT);

	VkMemoryAllocateInfo memAllocInfo = {};
	memAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
	memAllocInfo.allocationSize = 内存请求信息.size;
	memAllocInfo.memoryTypeIndex = 内存分配信息.memoryTypeIndex;

	err = vkAllocateMemory(m_Data.m_设备, &memAllocInfo, nullptr, &(m_Data.m_Mem));
	if (err != VK_SUCCESS) {
		throw std::runtime_error("分配CPU专属内存失败（可能超HOST_VISIBLE限制，GTX 1060建议≤3GB）");
	}


	m_Data.m_Buffer_info.buffer = m_Data.m_Buf;
	m_Data.m_Buffer_info.offset = 0;
	m_Data.m_Buffer_info.range = 内存请求信息.size;
	if (vkBindBufferMemory(m_Data.m_设备, m_Data.m_Buf, m_Data.m_Mem, 0) != VK_SUCCESS) {
		throw std::runtime_error("绑定CPU Buffer和内存失败");
	}

	return err;
}

void S_VkArray缓存::f_fillData(const void* data, uint64 bitSize) {
	if (m_Data.m_Buffer_info.range != bitSize) {
		f_分配(m_VkBufferUsageFlags, bitSize);
	}

	if (data && m_Data.m_Mem) {
		void* pData = 0;
		vkMapMemory(m_Data.m_设备, m_Data.m_Mem, 0, m_Data.m_Buffer_info.range, 0, &pData);
		memcpy(pData, data, bitSize);
		vkUnmapMemory(m_Data.m_设备, m_Data.m_Mem);
		pData = 0;
	}
}

void S_VkArray缓存::f_map() {
	switch (m_Type) {
		case E_板载缓存类型::e_光追底层加速结构:
		case E_板载缓存类型::e_光追顶层加速结构:
		case E_板载缓存类型::e_图像缓存: {
			break;
		}
		
		default: {
			m_mappedPtr = 0;
			VkResult err = vkMapMemory(m_Data.m_设备, m_Data.m_Mem, 0, m_Data.m_Buffer_info.range, 0, &m_mappedPtr);

			if (!m_mappedPtr || err) {
				std::cout << "vk缓存映射失败" << std::endl;
			}
			break;
		}
	}
}

void S_VkArray缓存::f_unmap() {
	vkUnmapMemory(m_Data.m_设备, m_Data.m_Mem);
	m_mappedPtr = nullptr;
}

void S_VkArray缓存::f_resize(uint64 bitSize) {
	assert(bitSize != 0);
	uint32 err{};

	if (m_预分配空间) {
		if (bitSize > m_Data.m_Buffer_info.range) {
			bitSize *= 1.5;
		}
		else if (bitSize < m_Data.m_Buffer_info.range * 0.77) {
			bitSize = m_Data.m_Buffer_info.range * 0.77;
		}
		else {
			return;
		}
	}
	elt_capacity = bitSize;

	S_VkBuffer tData = m_Data;
	m_Data = { 0 };

	if (m_VkBufferUsageFlags == VkBufferUsageFlagBits::VK_BUFFER_USAGE_TRANSFER_SRC_BIT) {
		err = f_分配拷贝缓存();
	}
	else {
		err = f_分配(m_VkBufferUsageFlags, elt_capacity);
	}
	
	if (err != VK_SUCCESS) {
		throw std::runtime_error("VK Buffer 分配失败");
	}
	f_copy((S_结构指针)&tData);
	
	if (tData.m_Buf) {
		vkFreeMemory(tData.m_设备, tData.m_Mem, 0);
		vkDestroyBuffer(tData.m_设备, tData.m_Buf, 0);
	}
}

void S_VkArray缓存::f_copy(S_结构指针 sObj) {
	const S_VkBuffer& tData = *((S_VkBuffer*)sObj);
	S_VK渲染环境* 绘图配置 = (S_VK渲染环境*)f_df_get绘图环境(m_Ctx);

	uint64 size = DEF_Min(m_Data.m_Buffer_info.range, tData.m_Buffer_info.range);


	//判断是否为已有对象拷贝
	if (tData.m_Buf) {
		
		assert(m_Data.m_Buf);
		if (绘图配置) {
			VkBufferCopy copyRegion = {};
			copyRegion.srcOffset = 0;
			copyRegion.dstOffset = 0;
			copyRegion.size = size;

			auto cmd = f_vk创建命令缓存(绘图配置);
			f_vk绑定命令缓存(绘图配置, cmd);
			vkCmdCopyBuffer(cmd, tData.m_Buf, m_Data.m_Buf, 1, &copyRegion);
			f_vk刷新命令缓存(绘图配置, cmd, true);
		}
		else {
			switch (m_Type) {
				case E_板载缓存类型::e_图像缓存: break;
				case E_板载缓存类型::e_光追底层加速结构:
				case E_板载缓存类型::e_光追顶层加速结构: {
					assert(m_Data.m_Buf);
					if (m_Data.m_Buf) {
						VkBufferCopy copyRegion = {};
						copyRegion.srcOffset = 0; // 从源缓冲区的偏移量
						copyRegion.dstOffset = 0; // 目标缓冲区的偏移量
						copyRegion.size = size; // 要复制的字节大小
			
						auto cmd = f_vk创建命令缓存(绘图配置);
						f_vk绑定命令缓存(绘图配置, cmd);
						vkCmdCopyBuffer(cmd, tData.m_Buf, m_Data.m_Buf, 1, &copyRegion);
						f_vk刷新命令缓存(绘图配置, cmd, true);
					}
					break;
				}
				
				default: {
					void* t_data = 0;
					
					vkMapMemory(m_Data.m_设备, m_Data.m_Mem, 0, m_Data.m_Buffer_info.range, 0, &m_mappedPtr);
					vkMapMemory(tData.m_设备, tData.m_Mem, 0, tData.m_Buffer_info.range, 0, &t_data);
			
					memcpy(m_mappedPtr, t_data, size);
			
					vkUnmapMemory(m_Data.m_设备, m_Data.m_Mem);
					vkUnmapMemory(tData.m_设备, tData.m_Mem);
					break;
				}
			}
		}
	}
}

//void S_VkArray缓存::f_change板载缓存(E_板载缓存类型 memType) {
//	void* t_data = calloc(m_Size, m_Offset);
//
//	m_mappedPtr = nullptr;
//	vkMapMemory(m_Data.m_设备, m_Data.m_Mem, 0, m_Data.m_Buffer_info.range, 0, (void**)&m_mappedPtr);
//	uint64 size = m_Size * m_Offset;
//	memcpy(t_data, m_mappedPtr, size);
//	vkUnmapMemory(m_Data.m_设备, m_Data.m_Mem);
//	m_mappedPtr = nullptr;
//
//	if (m_Data.m_Buf) {
//		vkDestroyBuffer(m_Data.m_设备, m_Data.m_Buf, 0);
//		vkFreeMemory(m_Data.m_设备, m_Data.m_Mem, 0);
//
//		m_Data.m_Buf = 0;
//		m_Data.m_Mem = 0;
//	}
//
//	f_分配(f_getAPI缓存类型(memType), m_Data.m_Buffer_info.range);
//
//	f_map();
//	memcpy(m_mappedPtr, t_data, size);
//	f_unmap();
//
//	free(t_data);
//}




uint64 f_buf_getAddress(S_板载缓存* buf) {
	S_VkArray缓存* vkbuf = static_cast<S_VkArray缓存*>(buf);

	switch (buf->m_Type) {
		case E_板载缓存类型::e_光追底层加速结构:
		case E_板载缓存类型::e_光追顶层加速结构: {
			//auto di = f_vk_get绘图环境(vkbuf->m_Ctx);
			auto di = f_vk_get绘图框架(vkbuf->m_Ctx);
			VkAccelerationStructureDeviceAddressInfoKHR accelerationDeviceAddressInfo{};
			accelerationDeviceAddressInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR;
			accelerationDeviceAddressInfo.accelerationStructure = vkbuf->m_光追加速结构;
			return di->vkGetAccelerationStructureDeviceAddress(vkbuf->m_Data.m_设备, &accelerationDeviceAddressInfo);
		}
		default:
			VkBufferDeviceAddressInfo bufDeviceAI{};
			bufDeviceAI.buffer = vkbuf->m_Data.m_Buf;
			bufDeviceAI.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO;
			return vkGetBufferDeviceAddress(vkbuf->m_Data.m_设备, &bufDeviceAI);
	}

	return 0;
}

uint64 f_buf_get加速结构(S_板载缓存* buf) {
	S_VkArray缓存* vkbuf = static_cast<S_VkArray缓存*>(buf);

	switch (buf->m_Type) {
		case E_板载缓存类型::e_光追底层加速结构:
		case E_板载缓存类型::e_光追顶层加速结构: {
			auto di = f_vk_get绘图框架(vkbuf->m_Ctx);
			//auto di = f_vk_get绘图环境(vkbuf->m_Ctx);
			VkAccelerationStructureDeviceAddressInfoKHR accelerationDeviceAddressInfo{};
			accelerationDeviceAddressInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR;
			accelerationDeviceAddressInfo.accelerationStructure = vkbuf->m_光追加速结构;
			return di->vkGetAccelerationStructureDeviceAddress(vkbuf->m_Data.m_设备, &accelerationDeviceAddressInfo);
		}
		default:
			VkBufferDeviceAddressInfo bufDeviceAI{};
			bufDeviceAI.buffer = vkbuf->m_Data.m_Buf;
			bufDeviceAI.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO;
			return vkGetBufferDeviceAddress(vkbuf->m_Data.m_设备, &bufDeviceAI);
	}

	return 0;
}

void f_bm_添加更新缓存列队(std::unique_ptr<C_缓存列队数据>&& data) {
	g缓存拷贝列队[*data].push_back(std::move(data));
}

void f_bm_刷新缓存到GPU() {
	
	for (auto& e : g缓存拷贝列队) {
		std::vector<VkBufferCopy> 拷贝区间;
		拷贝区间.reserve(e.second.size());
		if(e.second.size() <= 0) continue;

		for (auto& 拷贝区间数据 : e.second) {
			auto m = 拷贝区间数据->f_分配空间();

			if (m.m_数量) 拷贝区间.push_back({});
		}
		
		S_VkArray缓存* buf = static_cast<S_VkArray缓存*>(e.first);

		if(buf->m_mappedPtr) buf->f_unmap();
		f_buf_resize(buf, buf->m_分配器.maxNum);
		buf->f_map();


		for (auto& 拷贝区间数据 : e.second) {
			拷贝区间数据->f_拷贝到GPU();
		}

		uint64 nonCoherentAtomSize = f_vk_get物理设备属性(buf->m_Ctx).m_nonCoherentAtomSize;
		//uint64 nonCoherentAtomSize = buf->m_Offset;
		auto device = f_vk_getDevice(buf->m_Ctx);
		VkMappedMemoryRange range{};
		range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
		range.offset = 0;
		range.size = ((buf->m_Data.m_Buffer_info.range) / nonCoherentAtomSize) * nonCoherentAtomSize;
		//range.size = VK_WHOLE_SIZE;
		range.memory = buf->m_Data.m_Mem;

		vkFlushMappedMemoryRanges(device, 1, &range);
		e.second.clear();
	}
}


uint64 f_buf_getOffsetAddress(S_GPU内存块& 块, uint64 offset) {
	S_VkArray缓存* vkbuf = static_cast<S_VkArray缓存*>(块.m_Buf);

	VkDeviceAddress ptr;
	switch (vkbuf->m_Type) {
		case E_板载缓存类型::e_光追底层加速结构:
		case E_板载缓存类型::e_光追顶层加速结构: {
			auto di = f_vk_get绘图框架(vkbuf->m_Ctx);
			//auto di = f_vk_get绘图环境(vkbuf->m_Ctx);
			VkAccelerationStructureDeviceAddressInfoKHR accelerationDeviceAddressInfo{};
			accelerationDeviceAddressInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR;
			accelerationDeviceAddressInfo.accelerationStructure = vkbuf->m_光追加速结构;
			ptr = di->vkGetAccelerationStructureDeviceAddress(vkbuf->m_Data.m_设备, &accelerationDeviceAddressInfo);
			break;
		}
		default: {
			VkBufferDeviceAddressInfo bufDeviceAI{};
			bufDeviceAI.buffer = vkbuf->m_Data.m_Buf;
			bufDeviceAI.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO;
			ptr = vkGetBufferDeviceAddress(vkbuf->m_Data.m_设备, &bufDeviceAI);
			break;
		}
	}

	return ptr + (块.m_Mem.m_偏移 + offset) * uint64(vkbuf->m_Offset);
}

uint64 f_buf_getAddress2(S_GPU内存块& 内存块) {
	assert(内存块.m_Buf);
	if (!内存块.m_Buf->m_GPU_Address) {
		内存块.m_Buf->m_GPU_Address = f_buf_getAddress(内存块.m_Buf);
	}
	return 内存块.m_Buf->m_GPU_Address + (uint64(内存块.m_Mem.m_偏移) * 内存块.m_Buf->m_Offset);
}


//Inline uint64 f_GPU内存偏移ID(const S_GPU偏移大小& 块) {
//	return 块.m_偏移 | (uint64(块.m_数量)<<32);
//}


S_GPU偏移大小 f_buf_galloc(S_板载缓存* buf, uint64 num) {
	S_GPU偏移大小 新块{};
	std::lock_guard<std::mutex> guard(buf->m_分配块内存锁);

	uint32 回收站元素数量 = buf->m_分配器.m_内存回收偏移.size();
	if (回收站元素数量) {
		auto* 回收ptr = buf->m_分配器.m_内存回收偏移.data();
		
		for (uint32 i = 0; i < 回收站元素数量; ++i) {
			S_GPU偏移大小 空闲内存 = 回收ptr[i];

			if (num <= 空闲内存.m_数量) {
				新块 = { 空闲内存.m_偏移, num};

				空闲内存.m_数量 -= num;
				if (空闲内存.m_数量) {
					空闲内存.m_偏移 += num;
					回收ptr[i] = 空闲内存;
				}
				else {
					buf->m_分配器.m_内存回收偏移.erase(buf->m_分配器.m_内存回收偏移.begin() + i);
				}
				
				buf->m_分配器.m_内存分配偏移.insert(新块.m_偏移);
				return 新块;
			}
		}
	}

	if(!新块.m_数量) {
		新块 = { buf->m_分配器.maxNum, num };
		buf->m_分配器.maxNum += 新块.m_数量;
	}

	assert(buf->m_分配器.m_内存分配偏移.find(新块.m_偏移) == buf->m_分配器.m_内存分配偏移.end());
	buf->m_分配器.m_内存分配偏移.insert(新块.m_偏移);


	if (num && !buf->m_流) {
		if(buf->m_mappedPtr) buf->f_unmap();
		f_buf_resize(buf, buf->m_分配器.maxNum);
		buf->f_map();
	}
	return 新块;
}

void f_buf_gfree(S_板载缓存* buf, S_GPU偏移大小& 块) {
	std::lock_guard<std::mutex> guard(buf->m_分配块内存锁);

	if (buf->m_分配器.m_内存分配偏移.find(块.m_偏移) != buf->m_分配器.m_内存分配偏移.end()) {
		buf->m_分配器.m_内存分配偏移.erase(块.m_偏移);

		uint32 回收数量 = buf->m_分配器.m_内存回收偏移.size();
		auto* 回收ptr = buf->m_分配器.m_内存回收偏移.data();

		for (uint32 i = 0; i < 回收数量; ++i) {
			auto 回收块 = 回收ptr[i];
			
			if (回收块.m_偏移 + 回收块.m_数量 == 块.m_偏移) {
				回收ptr[i].m_数量 += 块.m_数量;
				return;
			}
		}
		buf->m_分配器.m_内存回收偏移.push_back(块);
	}
	else {
		std::cout<<"释放GPU内存错误: 没有找到已有的块 "<< 块.m_偏移 << " " << 块.m_数量 << std::endl;
	}
}

void f_bm_resize(S_GPU内存块& 块, uint64 newSize) {
	if (newSize > 块.m_Mem.m_数量 || newSize < 块.m_Mem.m_数量) {
		S_GPU内存块 新块 = f_bm_alloc(块.m_Buf, newSize);

		if (新块.m_Buf->m_mappedPtr && !块.m_Buf->m_流) {
			块.m_Buf->m_分配块内存锁.lock();
			uint8* Dst = &(((uint8*)(新块.m_Buf->m_mappedPtr))[新块.m_Mem.m_偏移 * 新块.m_Buf->m_Offset]);
			uint8* Src = &(((uint8*)(块.m_Buf->m_mappedPtr))[块.m_Mem.m_偏移 * 块.m_Buf->m_Offset]);
			memcpy(Dst, Src, DEF_Min(块.m_Mem.m_数量, 新块.m_Mem.m_数量) * 块.m_Buf->m_Offset);
			块.m_Buf->m_分配块内存锁.unlock();
		}

		f_bm_erase(块);
		块 = 新块;
	}
}



//VkAccelerationStructureKHR f_vkBuf_create加速结构(S_VkArray缓存* buf, VkAccelerationStructureTypeKHR type, VkAccelerationStructureBuildSizesInfoKHR buildSizeInfo) {
	//VkAccelerationStructureKHR as{};
	// Acceleration structure
	/*VkAccelerationStructureCreateInfoKHR accelerationStructureCreate_info{};
	accelerationStructureCreate_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR;
	accelerationStructureCreate_info.buffer = buf->m_几何体.m_Buf;
	accelerationStructureCreate_info.size = buildSizeInfo.accelerationStructureSize;
	accelerationStructureCreate_info.type = type;
	vkCreateAccelerationStructureKHR(buf->m_几何体.m_设备, &accelerationStructureCreate_info, nullptr, &as);

	// AS device address
	VkAccelerationStructureDeviceAddressInfoKHR accelerationDeviceAddressInfo{};
	accelerationDeviceAddressInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR;
	accelerationDeviceAddressInfo.accelerationStructure = as;
	vkGetAccelerationStructureDeviceAddressKHR(buf->m_几何体.m_设备, &accelerationDeviceAddressInfo);*/
//	return as;
//}

void* f_buf_get加速结构(S_GPU内存块& 块) {
	return f_buf_get加速结构(块, 0, 块.m_Mem.m_数量);
}

void* f_buf_get加速结构(S_GPU内存块& 块, uint32 offset, uint32 count) {
	auto 绘图配置 = f_vk_get绘图框架(块.m_Buf->m_Ctx);
	VkWriteDescriptorSetAccelerationStructureKHR* 光追结构传入参数 = ((VkWriteDescriptorSetAccelerationStructureKHR*)(块.m_Acc));

	if (光追结构传入参数) {
		绘图配置->vkDestroyAccelerationStructure(f_vk_getDevice(块.m_Buf->m_Ctx), (VkAccelerationStructureKHR)块.m_As, nullptr);
	}
	else {
		光追结构传入参数 = (VkWriteDescriptorSetAccelerationStructureKHR*)malloc(sizeof(VkWriteDescriptorSetAccelerationStructureKHR));

		(*光追结构传入参数) = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR };
		(*光追结构传入参数).accelerationStructureCount = 1;

		块.m_Acc = 光追结构传入参数;
	}


	VkAccelerationStructureCreateInfoKHR 加速结构创建信息{ VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR };
	加速结构创建信息.buffer = ((S_VkArray缓存*)块.m_Buf)->m_Data.m_Buf;
	加速结构创建信息.type = VkAccelerationStructureTypeKHR(f_getAPI光追加速缓存类型(块.m_Buf->m_Type));
	加速结构创建信息.size = count;
	加速结构创建信息.offset = 块.m_Mem.m_偏移 + offset;


	块.m_As = nullptr;
	绘图配置->vkCreateAccelerationStructure(f_vk_getDevice(块.m_Buf->m_Ctx), &加速结构创建信息, nullptr, (VkAccelerationStructureKHR*)&(块.m_As));
	光追结构传入参数->pAccelerationStructures = (VkAccelerationStructureKHR*)&(块.m_As);

	return 块.m_As;
}



S_板载缓存* f_buffer_创建拷贝缓存(S_板载缓存& 主缓存对象) {
	S_VkArray缓存& pb = *static_cast<S_VkArray缓存*>(&主缓存对象);

	S_VkArray缓存* buf = new S_VkArray缓存(pb.m_Ctx, pb.m_Type, pb.m_Offset, 1);

	return buf;
}